//
// Created by francklinson on 2021/11/26 AT 10:43.
// May Saint Diana bless you!
//

#include <windows.h>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <iostream>

DWORD WINAPI reset(LPVOID p)
{
    boost::shared_ptr<int> *sh = static_cast<boost::shared_ptr<int>*>(p);
    sh->reset();
    return 0;
}

DWORD WINAPI print(LPVOID p)
{
    boost::weak_ptr<int> *w = static_cast<boost::weak_ptr<int>*>(p);
    boost::shared_ptr<int> sh = w->lock();
    if (sh)
        std::cout << *sh << std::endl;
    return 0;
}
/**
 * boost::weak_ptr 必定总是通过 boost::shared_ptr 来初始化的。
 * 一旦初始化之后，它基本上只提供一个有用的方法: lock()。
 * 此方法返回的boost::shared_ptr 与用来初始化弱指针的共享指针共享所有权。
 * 如果这个共享指针不含有任何对象，返回的共享指针也将是空的。

    当函数需要一个由共享指针所管理的对象，而这个对象的生存期又不依赖于这个函数时，就可以使用弱指针。
    只要程序中还有一个共享指针掌管着这个对象，函数就可以使用该对象。
    如果共享指针复位了，就算函数里能得到一个共享指针，对象也不存在了。
 * @return
 */
int main()
{
    boost::shared_ptr<int> sh(new int(99));
    boost::weak_ptr<int> w(sh);
    HANDLE threads[2];
    threads[0] = CreateThread(0, 0, reset, &sh, 0, 0);
    threads[1] = CreateThread(0, 0, print, &w, 0, 0);
    /**
     * 程序启动之后，reset() 和 print() 就都开始执行了。
     * 不过执行顺序是不确定的。 这就导致了一个潜在的问题：reset() 线程在销毁对象的时候print() 线程可能正在访问它。
       通过调用弱指针的 lock() 函数可以解决这个问题：如果对象存在，那么 lock() 函数返回的共享指针指向这个合法的对象。
       否则，返回的共享指针被设置为0，这等价于标准的null指针。
     */
    WaitForMultipleObjects(2, threads, TRUE, INFINITE);
}